package game;

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;

import doublelinkedlist.LinkedList;
import doublelinkedlist.exceptions.InvalidDataParameterException;
import doublelinkedlist.exceptions.LinkedListIndexException;

/**
 * The main class of the project, representing the game, has menu, MVC, two
 * players, and turns
 * 
 * @author Home
 * 
 */
public class Game {

	private static final int MAXIMUM_NUMBER_OF_HIGHSCORES = 10;
	private static final int MAXIMUM_DIGITS_OF_SCORE = 2;
	private static final File[] highscoreFiles = {
			new File("highscores_5x5.txt"), new File("highscores_7x7.txt"),
			new File("highscores_9x9.txt") };
	private static File currentHighscores;
	private static LinkedList highscoresList = new LinkedList();

	private GameMenu menu;
	private GameMVC personalMVC;
	private Player playerOne, playerTwo;
	private int turns;

	/**
	 * plays the game
	 */
	public void play() {
		/*
		 * cycle{playTurn() ---- if(isOver) - back to the menu...}
		 */
	}

	/*
	 * asks the user for line input(row, column, direction)
	 */
	private void askForLine() {
		/*
		 * ask; boolean scores = fillInLine(Line l); if(scores). . . --some
		 * code--
		 */
	}

	/*
	 * plays a single turn
	 */
	private void playTurn() {
		/*
		 * turns++; --some code-- askForLine();
		 */
	}

	/*
	 * determines if the game is over
	 */
	private boolean isOver(int currentPlayerScore) {

		return false;

	}

	/*
	 * saving high scores in the end of the game, if there are such. Returns if
	 * the player has made it to the high scores
	 */
	private static boolean saveHighscore(Player player, int boardSize) {

		setCurrentHighscoreFile(boardSize);
		getHighscoresFromFileToList(currentHighscores);
		int newScore = player.getCurrentScore();
		String newScoreLine = "Name: " + player.getName() + " -> Score: "
				+ newScore;
		boolean playerHasHighscore = updateHighscoresList(newScore,
				newScoreLine);
		writeHighscoresListToFile(currentHighscores);
		highscoresList = new LinkedList();
		return playerHasHighscore;

	}

	/*
	 * returns if the given score has made it to the high scores
	 */
	private static boolean updateHighscoresList(int newScore,
			String newScoreLine) {

		if (!highscoresList.contains(newScoreLine)) {
			boolean inserted = false;
			for (int i = 0; i < highscoresList.getSize(); i++) {
				try {
					String scoreLine = highscoresList.get(i).toString();
					String scoreText = scoreLine.substring(scoreLine.length()
							- MAXIMUM_DIGITS_OF_SCORE, scoreLine.length());
					int score = Integer.parseInt(scoreText.replaceAll("[^0-9]",
							""));
					if (newScore >= score) {
						try {
							highscoresList.insertAt(i, newScoreLine);
							inserted = true;
						} catch (InvalidDataParameterException e) {
							e.printStackTrace();
						}
						break;
					}
				} catch (LinkedListIndexException e) {
					e.printStackTrace();
				}
			}
			if (!inserted) {
				try {
					highscoresList.add(newScoreLine);
				} catch (InvalidDataParameterException e) {
					e.printStackTrace();
				}
			}
			if (highscoresList.getSize() > MAXIMUM_NUMBER_OF_HIGHSCORES) {
				try {
					highscoresList.remove(highscoresList.getSize() - 1);
				} catch (LinkedListIndexException e) {
					e.printStackTrace();
				}
			}
		}
		if (highscoresList.contains(newScoreLine)) {
			return true;
		}
		return false;

	}

	private static void writeHighscoresListToFile(File highscoresFile) {

		try {
			BufferedWriter writer = new BufferedWriter(new FileWriter(
					highscoresFile));
			for (int i = 0; i < highscoresList.getSize(); i++) {
				try {
					writer.write(highscoresList.get(i).toString());
					if (i != highscoresList.getSize() - 1) {
						writer.write(System.getProperty("line.separator"));
					}
				} catch (LinkedListIndexException e) {
					e.printStackTrace();
				}
			}
			writer.close();
		} catch (IOException e) {
			e.printStackTrace();
		}

	}

	private static void getHighscoresFromFileToList(File highscoresFile) {

		try {
			BufferedReader reader = new BufferedReader(new FileReader(
					highscoresFile));
			String textLine = reader.readLine();

			while (textLine != null) {
				try {
					highscoresList.add(textLine);
				} catch (InvalidDataParameterException e) {
					e.printStackTrace();
				}
				textLine = reader.readLine();
			}
			reader.close();
		} catch (IOException e) {
			e.printStackTrace();
		}

	}

	public static String allHighscoresToString() {

		String allHighscores = "";
		for (int i = 0; i < highscoreFiles.length; i++) {
			allHighscores += "Highscores for game "
					+ GameMenu.getAvailableSizeAt(i) + "x"
					+ GameMenu.getAvailableSizeAt(i) + ":\n";
			allHighscores += getHighscoreFileToString(highscoreFiles[i]) + "\n";
		}
		return allHighscores;

	}

	private static String getHighscoreFileToString(File highscoresFile) {

		getHighscoresFromFileToList(highscoresFile);
		String highscoresText = "";
		for (int i = 0; i < highscoresList.getSize(); i++) {
			try {
				highscoresText += "\t" + highscoresList.get(i) + "\n";
			} catch (LinkedListIndexException e) {
				e.printStackTrace();
			}
		}
		highscoresList = new LinkedList();
		return highscoresText;

	}

	/*
	 * cases depend on the available sizes in the game menu!!
	 */
	private static void setCurrentHighscoreFile(int boardSize) {

		switch (boardSize) {
		case 5:
			currentHighscores = highscoreFiles[0];
			break;
		case 7:
			currentHighscores = highscoreFiles[1];
			break;
		case 9:
			currentHighscores = highscoreFiles[2];
			break;
		default:
			System.err
					.println("Can't find highscore file for the given board size!");
		}

	}

}
